const express = require("express");
var bodyParser = require("body-parser");
// 导入 cors 模块
const cors = require("cors");
// 导入db模块
const db = require("./db");
const userRouter = require("./router/user");
const logRouter = require("./router/log");
const publicRouter = require("./router/public");
// 导入配置文件
const config = require("./config");
// 解析 token 的中间件
const expressJWT = require("express-jwt");

const app = express();
// 配置请求体大小限制
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
// 全局响应数据中间件
app.use((req, res, next) => {
  res.sendData = (data, statusCode = 200) => {
    res.setHeader("Content-Type", "application/json");
    res.status(statusCode).send(JSON.stringify(data));
  };
  next();
});
// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(
  expressJWT({ secret: config.jwtSecretKey }).unless({
    path: [
      /^\/api\//,
      /^\/public\//,
    ],
  })
);
// 全局验证 Token单点登录 的中间件
app.use( async (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (token) {
    const { user_id } = req.user;
    const sql = "select * from auth_token where user_id=? AND token=?";
    try {
      const results = await db.query(sql, [user_id, token]);
      if (results.length === 0) return res.sendData({ message: "该账号在其他设备已登陆，请重新登录！" }, 403);
      next();
    } catch (err) {
      return res.sendData({ message: "Failed to execute query:" + err }, 500);
    }
  } else {
    next();
  }
});
// 路由一定要放expressJwt后边！！！！！！！
app.use("/api", userRouter);
app.use("/log", logRouter);
app.use("/public", publicRouter);
// 定义全局错误处理中间件
app.use((err, req, res, next) => {
  // 捕获身份认证失败的错误
  if (err.name === "UnauthorizedError")
    return res.sendData({ message: "身份认证失败！请重新登录！" }, 401);
  console.error(err.stack);
  res.status(500).send("Internal Server Error");
});
// 程序退出时关闭数据库连接池
process.on("exit", () => {
  db.close();
});
app.listen(9001, () => {
  console.log("服务器运行在 http://127.0.0.1:9001");
});
